package com.lty.controller;

import com.lty.common.BaseResponse;
import com.lty.common.ResultUtils;
import com.lty.redis.RateLimiter;
import com.lty.redis.RedisUtil;
import com.lty.redis.lock.Callback;
import com.lty.redis.lock.RedisLockTemplate;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * Redis测试接口
 */
@Slf4j
@RequestMapping("/redis")
@RestController
public class RedisController {

    @Resource
    public RedisUtil redisUtil;

    @Resource
    public RedisLockTemplate redisLockTemplate;

    @Resource
    public RedisTemplate redisTemplate;

    @RequestMapping(value = "/set", method = RequestMethod.POST)
    public BaseResponse<String> setRedis(String key, String value, Long expireTime) {
        redisUtil.set(key, value, expireTime);
        return ResultUtils.success("success");
    }

    @RequestMapping(value = "/get", method = RequestMethod.POST)
    public BaseResponse<String> getRedis(String key) {
        String value = redisUtil.get(key);
        return ResultUtils.success(value);
    }

    @ApiOperation("生成业务标识")
    @RequestMapping(value = "/getBusinessId", method = RequestMethod.GET)
    public BaseResponse<String> getBusinessId() {
        String value = redisUtil.getBusinessId("project", "S");
        return ResultUtils.success(value);
    }

    @ApiOperation("删除key根据正则表达式")
    @RequestMapping(value = "/flush", method = RequestMethod.POST)
    public BaseResponse<Integer> flush(String pattern) {
        long l = redisUtil.deleteKeysByPattern(pattern);
        log.info("删除{}条数据", l);
        return ResultUtils.success((int) l);
    }

    @RateLimiter(rate = 1, rateInterval = 10000L, ipLimit = true)
    @ApiOperation("Redis限流测试")
    @RequestMapping(value = "/limit", method = RequestMethod.POST)
    public BaseResponse<String> limit() {
        return ResultUtils.success("success");
    }

    @RequestMapping(value = "/lockAndLimit", method = RequestMethod.GET)
    //@RateLimiter(rate = 1, rateInterval = 5000)
    @ApiOperation(value = "分布式锁限流测试")
    public BaseResponse<Boolean> test() {
        Object execute = redisLockTemplate.execute("订单流水号", 3, null, TimeUnit.SECONDS, new Callback() {
            @Override
            public Object onGetLock() {
                // TODO 获得锁后要做的事
                log.info("生成订单流水号");

                // 模拟耗时任务线程
                //try {
                //    Thread.sleep(5000);
                //} catch (InterruptedException e) {
                //    e.printStackTrace();
                //}

                return true;
            }

            @Override
            public Object onTimeout() {
                // TODO 未获取到锁（获取锁超时）后要做的事
                log.info("oops 没拿到锁");
                return false;
            }
        });

        return ResultUtils.success(((Boolean) execute));
    }

    @RequestMapping(value = "/send", method = RequestMethod.POST)
    public BaseResponse<Boolean> sendMessage(String message) {
        redisTemplate.convertAndSend("redis:topic", message);
        return ResultUtils.success(true);
    }
}
